package com.dog.basics.netty.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.dog.basics.bean.dto.netty.NettyCommonDto;
import com.dog.basics.bean.dto.netty.NettyWheelchairDto;
import com.dog.basics.netty.protobuf.dto.DogNewsContentDto;
import com.dog.basics.netty.util.ConstantUtil;
import com.dog.basics.netty.util.SessionSocketHolder;
import com.rabbitmq.client.Channel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @description: 通讯业务
 * @author: He
 * @date: Created in 2020/10/13 14:35
 * @version: 1.0
 * @modified By:
 */
@Service
@Log4j2
public class BusinessService {

    /**
     * 公共业务处理
     *
     * @param dto     处理实体
     * @param channel
     * @param headers guonh 2020年10月13日
     */
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "EX-BUSINESS-MQ", arguments = {
            @Argument(name = "alternate-exchange", value = "exchange-unroute")}), value = @Queue(value = "QU-BUSINESS-MQ"), key = "SERVICE-COMMON"))
    public void businessCommonService(@Payload NettyCommonDto dto, Channel channel, @Headers Map<String, Object> headers) {
        log.info("公共业务处理:{}" + JSONUtil.toJsonStr(dto));
        // 根据设备标识查询设备通道
        NioSocketChannel socketChannel = SessionSocketHolder.get(dto.getDevId());
        // 判断是否有通道存在
        if (ObjectUtil.isNotNull(socketChannel)) {
            // 判断什么类型的消息
            DogNewsContentDto.Message.Builder builder;
            switch (dto.getMsgType()) {
                case ConstantUtil.REMOTEUPGRADE:
                    // 远程在线升级
                    builder = DogNewsContentDto.Message.newBuilder().setMsgType(dto.getMsgType()).setMsgCode(1);
                    // 判断是否为自定义数字信息 - 有则发送给硬件
                    if (ObjectUtil.isNotNull(dto.getCustomVal())) {
                        builder.setCustomizeType(dto.getCustomVal());
                    }
                    // 判断是否为版本号信息 - 有则发送给硬件
                    if (StrUtil.isNotBlank(dto.getFirmwareVersion())) {
                        builder.setImeiVersion(dto.getFirmwareVersion());
                    }
                    socketChannel.writeAndFlush(builder.build());
                    break;
                case ConstantUtil.REMOTEREBOOT:
                case ConstantUtil.REMOTESHUTDOWN:
                case ConstantUtil.REMOTECUSTOMCONTROL:
                    // 远程重启、远程关机、远程自定义
                    builder = DogNewsContentDto.Message.newBuilder().setMsgType(dto.getMsgType()).setMsgCode(1);
                    // 判断是否为自定义数字信息 - 有则发送给硬件
                    if (ObjectUtil.isNotNull(dto.getCustomVal())) {
                        builder.setCustomizeType(dto.getCustomVal());
                    }
                    socketChannel.writeAndFlush(builder.build());
                    break;
                default:
                    log.error("公共业务设备未知消息类型 : [ 设备标识:{} 处理值:{} ]", dto.getDevId(), JSONUtil.toJsonStr(dto));
                    break;
            }
        } else {
            log.error("公共业务设备通道不在线 : [ 设备标识:{} 处理值:{} ]", dto.getDevId(), JSONUtil.toJsonStr(dto));
        }
        // 是否释放消息 资源
        long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        channel.basicAck(deliveryTag, false);
    }


    /**
     * 轮椅定制协议业务
     *
     * @param dto     接收实体
     * @param channel
     * @param headers guonh 2020年10月14日
     */
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "EX-WHEELCHAIR-MQ", arguments = {
            @Argument(name = "alternate-exchange", value = "exchange-unroute")}), value = @Queue(value = "QU-WHEELCHAIR-MQ"), key = "SERVICE-COMMON-WHEELCHAIR"))
    public void wheelchairCommonService(@Payload NettyWheelchairDto dto, Channel channel, @Headers Map<String, Object> headers) {
        log.info("轮椅定制协议:{}" + JSONUtil.toJsonStr(dto));
        System.out.println("轮椅定制协议:{}" + JSONUtil.toJsonStr(dto));
        // 根据设备标识查询设备通道
        NioSocketChannel socketChannel = SessionSocketHolder.get(dto.getDevId());
        // 判断是否有通道存在
        if (ObjectUtil.isNotNull(socketChannel)) {
            // 判断什么类型的消息
            switch (dto.getMsgType()) {
                case ConstantUtil.RENTINGAWHEELCHAIR:
                case ConstantUtil.UNLOCKINGTEST:
                case ConstantUtil.GETLOCKSTATE:
                    // 租赁轮椅（开锁）丶 开锁测试 丶 查询轮椅状态（锁状态）
                    DogNewsContentDto.Message.Builder builder = DogNewsContentDto.Message.newBuilder().setMsgType(dto.getMsgType()).setMsgCode(1);
                    // 判断锁通道是否为空 - 不为空则发送
                    if (ObjectUtil.isNotNull(dto.getLockport())) {
                        builder.setLockport(dto.getLockport());
                    }
                    // 判断轮椅卡号否为空 - 不为空则发送
                    if (ObjectUtil.isNotNull(dto.getIDcard())) {
                        builder.setIDcard(dto.getIDcard());
                    }
                    socketChannel.writeAndFlush(builder.build());
                    break;
                default:
                    log.error("轮椅设备未知消息类型 : [ 设备标识:{} 处理值:{} ]", dto.getDevId(), JSONUtil.toJsonStr(dto));
                    break;
            }
        } else {
            log.error("轮椅设备通道不在线 : [ 设备标识:{} 处理值:{} ]", dto.getDevId(), JSONUtil.toJsonStr(dto));
        }
        // 是否释放消息 资源
        long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        channel.basicAck(deliveryTag, false);
    }


}